package at.fhj.itm.weather;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;

/**
 * The Class WeatherData is responsible for parsing the XML Data from the URL
 * The required information will be extracted from the XML and will be placed in
 * the setter methods
 * 
 * @author Christian Tassler & Andreas Reibenbacher
 */
public class WeatherData {

	// Constructor
	public WeatherData(String urlStr) throws MalformedURLException {
		parseXML(new URL(urlStr));
	}

	// Variables
	private String info = null;
	private String city = null;
	private String country = null;
	private String code = null;

	private URL imageToday = null;
	private String temperature = null;
	private String unitTemperature = null;
	private String infoText = null;
	private String pressure = null;
	private String humidity = null;

	private String pressureUnit = null;
	private String directionWind = null;
	private String speedWind = null;
	private String speedUnit = null;
	private String sunrise = null;
	private String sunset = null;

	private String dayTomorrow = null;
	private String dateTomorrow = null;
	private String tempLowTomorrow = null;
	private String tempHighTomorrow = null;
	private URL imageTomorrow = null;
	private String codeTomorrow = null;
	private String infoTomorrow = null;

	private String day2Days = null;
	private String date2Days = null;
	private String tempLow2Days = null;
	private String tempHigh2Days = null;
	private URL image2Days = null;
	private String code2Days = null;
	private String info2Days = null;

	// Getter-Setter
	public String getInfoTomorrow() {
		return infoTomorrow;
	}

	public void setInfoTomorrow(String infoTomorrow) {
		this.infoTomorrow = infoTomorrow;
	}

	public String getInfo2Days() {
		return info2Days;
	}

	public void setInfo2Days(String info2Days) {
		this.info2Days = info2Days;
	}

	public String getInfo() {
		return info;
	}

	public void setInfo(String info) {
		this.info = info;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public URL getImageToday() {
		return imageToday;
	}

	public void setImageToday(URL imageToday) {
		this.imageToday = imageToday;
	}

	public String getTemperature() {
		return temperature;
	}

	public void setTemperature(String temperature) {
		this.temperature = temperature;
	}

	public String getUnitTemperature() {
		return unitTemperature;
	}

	public void setUnitTemperature(String unitTemperature) {
		this.unitTemperature = unitTemperature;
	}

	public String getInfoText() {
		return infoText;
	}

	public void setInfoText(String infoText) {
		this.infoText = infoText;
	}

	public String getHumidity() {
		return humidity;
	}

	public void setHumidity(String humidity) {
		this.humidity = humidity;
	}

	public String getPressure() {
		return pressure;
	}

	public void setPressure(String pressure) {
		this.pressure = pressure;
	}

	public String getPressureUnit() {
		return pressureUnit;
	}

	public void setPressureUnit(String pressureUnit) {
		this.pressureUnit = pressureUnit;
	}

	public String getDirectionWind() {
		return directionWind;
	}

	public void setDirectionWind(String directionWind) {
		this.directionWind = directionWind;
	}

	public String getSpeedWind() {
		return speedWind;
	}

	public void setSpeedWind(String speedWind) {
		this.speedWind = speedWind;
	}

	public String getSpeedUnit() {
		return speedUnit;
	}

	public void setSpeedUnit(String speedUnit) {
		this.speedUnit = speedUnit;
	}

	public String getSunrise() {
		return sunrise;
	}

	public void setSunrise(String sunrise) {
		this.sunrise = sunrise;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getSunset() {
		return sunset;
	}

	public void setSunset(String sunset) {
		this.sunset = sunset;
	}

	public String getDateTomorrow() {
		return dateTomorrow;
	}

	public void setDateTomorrow(String dateTomorrow) {
		this.dateTomorrow = dateTomorrow;
	}

	public String getTempLowTomorrow() {
		return tempLowTomorrow;
	}

	public void setTempLowTomorrow(String tempLowTomorrow) {
		this.tempLowTomorrow = tempLowTomorrow;
	}

	public String getTempHighTomorrow() {
		return tempHighTomorrow;
	}

	public void setTempHighTomorrow(String tempHighTomorrow) {
		this.tempHighTomorrow = tempHighTomorrow;
	}

	public URL getImageTomorrow() {
		return imageTomorrow;
	}

	public void setImageTomorrow(URL imageTomorrow) {
		this.imageTomorrow = imageTomorrow;
	}

	public String getCodeTomorrow() {
		return codeTomorrow;
	}

	public void setCodeTomorrow(String codeTomorrow) {
		this.codeTomorrow = codeTomorrow;
	}

	public String getCode2Days() {
		return code2Days;
	}

	public void setCode2Days(String code2Days) {
		this.code2Days = code2Days;
	}

	public String getDayTomorrow() {
		return dayTomorrow;
	}

	public void setDayTomorrow(String dayTomorrow) {
		this.dayTomorrow = dayTomorrow;
	}

	public String getDay2Days() {
		return day2Days;
	}

	public void setDay2Days(String day2Days) {
		this.day2Days = day2Days;
	}

	public String getDate2Days() {
		return date2Days;
	}

	public void setDate2Days(String date2Days) {
		this.date2Days = date2Days;
	}

	public String getTempLow2Days() {
		return tempLow2Days;
	}

	public void setTempLow2Days(String tempLow2Days) {
		this.tempLow2Days = tempLow2Days;
	}

	public String getTempHigh2Days() {
		return tempHigh2Days;
	}

	public void setTempHigh2Days(String tempHigh2Days) {
		this.tempHigh2Days = tempHigh2Days;
	}

	public URL getImage2Days() {
		return image2Days;
	}

	public void setImage2Days(URL image2Days) {
		this.image2Days = image2Days;
	}

	/**
	 * In this method the XML document will be handled with JDOM The required
	 * fields will be searched and assigned to the compatible setter
	 * 
	 * @param url
	 *            The URL of the XML data source - for the specific city
	 */
	private void parseXML(URL url) {
		try {
			// ---- Read XML file ----
			SAXBuilder builder = new SAXBuilder();
			Document doc;
			doc = builder.build(url);

			// ---- Get required information ----
			Element weather = doc.getRootElement();
			// Log.i("WeatherApp", "parseXML " + weather);
			Element channel = weather.getChild("channel");
			// Log.i("WeatherApp", "parseXML " + channel);
			Element title = channel.getChild("title");
			// Log.i("WeatherApp", "parseXML " + title);

			Namespace yweather = Namespace.getNamespace("yweather",
					"http://xml.weather.yahoo.com/ns/rss/1.0");
			Element yweatherlocation = channel.getChild("location", yweather);
			String locationCity = yweatherlocation.getAttributeValue("city");
			String locationCountry = yweatherlocation
					.getAttributeValue("country");
			this.setCity(locationCity);
			this.setCountry(locationCountry);
			// Log.i("WeatherApp", "parseXML " + locationCity);
			// Log.i("WeatherApp", "parseXML " + locationCountry);

			Element yweatherUnits = channel.getChild("units", yweather);
			String unitTemperature = yweatherUnits
					.getAttributeValue("temperature");
			String unitPressure = yweatherUnits.getAttributeValue("pressure");
			String unitSpeed = yweatherUnits.getAttributeValue("speed");
			this.setUnitTemperature(unitTemperature);
			this.setPressureUnit(unitPressure);
			this.setSpeedUnit(unitSpeed);
			// Log.i("WeatherApp", "parseXML " + unitTemperature);
			// Log.i("WeatherApp", "parseXML " + unitPressure);
			// Log.i("WeatherApp", "parseXML " + unitSpeed);

			Element yweatherWind = channel.getChild("wind", yweather);
			String windDirection = yweatherWind.getAttributeValue("direction");
			String windSpeed = yweatherWind.getAttributeValue("speed");
			this.setDirectionWind(windDirection);
			this.setSpeedWind(windSpeed);
			// Log.i("WeatherApp", "parseXML " + windDirection);
			// Log.i("WeatherApp", "parseXML " + windSpeed);

			Element yweatherAtmosphere = channel.getChild("atmosphere",
					yweather);
			String atmosphereHumidity = yweatherAtmosphere
					.getAttributeValue("humidity");
			String atmospherePressure = yweatherAtmosphere
					.getAttributeValue("pressure");
			this.setHumidity(atmosphereHumidity);
			this.setPressure(atmospherePressure);
			// Log.i("WeatherApp", "parseXML " + atmosphereHumidity);
			// Log.i("WeatherApp", "parseXML " + atmospherePressure);

			Element yweatherAstronomy = channel.getChild("astronomy", yweather);
			String astronomySunrise = yweatherAstronomy
					.getAttributeValue("sunrise");
			String astronomySunset = yweatherAstronomy
					.getAttributeValue("sunset");
			this.setSunrise(astronomySunrise);
			this.setSunset(astronomySunset);
			// Log.i("WeatherApp", "parseXML " + astronomySunrise);
			// Log.i("WeatherApp", "parseXML " + astronomySunset);

			Element item = channel.getChild("item");
			Element itemTitle = item.getChild("title");
			String itemTitleText = itemTitle.getText();
			this.setInfo(itemTitleText);

			Element description = item.getChild("description");

			Element yweatherCondition = item.getChild("condition", yweather);
			String itemText = item.getText();
			String conditionText = yweatherCondition.getAttributeValue("text");
			String conditionCode = yweatherCondition.getAttributeValue("code");
			String conditionTemp = yweatherCondition.getAttributeValue("temp");
			String conditionDate = yweatherCondition.getAttributeValue("date");
			this.setInfoText(conditionText);
			this.setCode(conditionCode);
			this.setTemperature(conditionTemp);

			// Log.i("WeatherApp", "parseXML " + itemText);
			// Log.i("WeatherApp", "parseXML " + conditionText);
			// Log.i("WeatherApp", "parseXML " + conditionCode);
			// Log.i("WeatherApp", "parseXML " + conditionTemp);
			// Log.i("WeatherApp", "parseXML " + conditionDate);

			List yweatherForecastListDay = item.getChildren("forecast",
					yweather);

			List forecastDaysList = new ArrayList();
			List forecastDateList = new ArrayList();
			List forecastTempLowList = new ArrayList();
			List forecastTempHighList = new ArrayList();
			List forecastCodeList = new ArrayList();
			List forecastInfoList = new ArrayList();

			List yweatherForecastList = item.getChildren("forecast", yweather);
			for (Object o : yweatherForecastList) {
				Element element = (Element) o;
				forecastDaysList.add(element.getAttributeValue("day"));
				forecastDateList.add(element.getAttributeValue("date"));
				forecastTempLowList.add(element.getAttributeValue("low"));
				forecastTempHighList.add(element.getAttributeValue("high"));
				forecastCodeList.add(element.getAttributeValue("code"));
				forecastInfoList.add(element.getAttributeValue("text"));
			}

			String forecastFirstDay = forecastDaysList.get(0).toString();
			this.setDayTomorrow(forecastFirstDay);
			String forecastSecondDay = forecastDaysList.get(1).toString();
			this.setDay2Days(forecastSecondDay);

			String forecastFirstDate = forecastDateList.get(0).toString();
			this.setDateTomorrow(forecastFirstDate);
			String forecastSecondDate = forecastDateList.get(1).toString();
			this.setDate2Days(forecastSecondDate);

			String forecastFirstLowTemp = forecastTempLowList.get(0).toString();
			this.setTempLowTomorrow(forecastFirstLowTemp);
			String forecastSecondLowTemp = forecastTempLowList.get(1)
					.toString();
			this.setTempLow2Days(forecastSecondLowTemp);

			String forecastFirstHighTemp = forecastTempHighList.get(0)
					.toString();
			this.setTempHighTomorrow(forecastFirstHighTemp);
			String forecastSecondHighTemp = forecastTempHighList.get(1)
					.toString();
			this.setTempHigh2Days(forecastSecondHighTemp);

			String forecastFirstCode = forecastCodeList.get(0).toString();
			this.setCodeTomorrow(forecastFirstCode);
			String forecastSecondCode = forecastCodeList.get(1).toString();
			this.setCode2Days(forecastSecondCode);

			String forecastFirstInfo = forecastInfoList.get(0).toString();
			this.setInfoTomorrow(forecastFirstInfo);
			String forecastSecondInfo = forecastInfoList.get(1).toString();
			this.setInfo2Days(forecastSecondInfo);

			// Log.i("WeatherApp", "parseXML " + forecastFirstDay);
			// Log.i("WeatherApp", "parseXML " + forecastFirstDate);
			// Log.i("WeatherApp", "parseXML " + forecastFirstLowTemp);
			// Log.i("WeatherApp", "parseXML " + forecastFirstHighTemp);
			// Log.i("WeatherApp", "parseXML " + forecastFirstCode);
			// Log.i("WeatherApp", "parseXML " + forecastFirstInfo);
			//
			// Log.i("WeatherApp", "parseXML " + forecastSecondDay);
			// Log.i("WeatherApp", "parseXML " + forecastSecondDate);
			// Log.i("WeatherApp", "parseXML " + forecastSecondLowTemp);
			// Log.i("WeatherApp", "parseXML " + forecastSecondHighTemp);
			// Log.i("WeatherApp", "parseXML " + forecastSecondCode);
			// Log.i("WeatherApp", "parseXML " + forecastSecondInfo);

		} catch (JDOMException e) {
			// Log.e("WeatherApp", "parseXML" + e.getMessage());
		} catch (IOException e) {
			// Log.e("WeatherApp", "parseXML" + e.getMessage());
		}

	}

}
